package com.swingson.properties.specificclass_impl;

import com.swingson.Swingson;
import com.swingson.SwingsonGui;
import com.swingson.jsonparser.JsonElement;
import com.swingson.other.ConditionAndAction;
import com.swingson.other.MethodExecutor;
import com.swingson.properties.AbstractAssignMethodPropertyProcessor;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JSpinner;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

/**
 * @author sad
 */
public class OnChangeSpinnerPropertyProcessor extends AbstractAssignMethodPropertyProcessor {

    static List<Class[]> argumentsVariants = new ArrayList<Class[]>() {
        {
            add(new Class[]{});//no parameters
            add(new Class[]{ChangeEvent.class});//no parameters
        }
    };

    public OnChangeSpinnerPropertyProcessor() {
    }

    @Override
    protected String getName() {
        return "On Change Event Listener";
    }

    @Override
    protected List<Class[]> methodArgumentsVariants() {
        return argumentsVariants;
    }

    @Override
    protected void attachMethod(JsonElement jsonElement, final JComponent component, final SwingsonGui gui, String propertyName, final MethodExecutor mExecutor, final int methodArgumentVariant, final ConditionAndAction conditionAndAction) {
        EventExecutor<ChangeEvent> executor = new EventExecutor<ChangeEvent>() {
            @Override
            public void execute(ChangeEvent event) {
                if (!Swingson.isEnabledUserInput()) {
                    return;
                }
                try {
                    switch (methodArgumentVariant) {
                        case 0:
                            mExecutor.invoke();
                            break;
                        case 1:
                            mExecutor.invoke(event);
                            break;
                    }
                    runAction(conditionAndAction, gui, component);
                } catch (Throwable ex) {
                    onError(gui, ex);
                }
            }
        };

        ChangeListenerWrapper listener = new ChangeListenerWrapper();
        listener.setOnChange(executor);
        ((JSpinner) component).addChangeListener(listener);

    }

    private class ChangeListenerWrapper implements ChangeListener {

        private EventExecutor onChange;

        public void setOnChange(EventExecutor onChange) {
            this.onChange = onChange;
        }

        @Override
        public void stateChanged(ChangeEvent e) {
            onChange.execute(e);
        }
    }
}
